from collections import defaultdict
import numpy
from scipy import sparse
from datetime import datetime
from sklearn.cross_validation import KFold
from sklearn.neighbors import NearestCentroid
from sklearn.dummy import DummyClassifier
from sklearn.metrics import classification_report
__author__ = 'pstalidis'
from ICT4Growth.ArtMAP2 import ArtMAP
# from ICT4Growth.ArtMAP import AdaptiveClustering
from ICT4Growth.ArtMAP2 import ReadaptiveClustering as AdaptiveClustering


path = "./datasets/jester_1/"
name = "jester_dataset_1_1.csv"

choices = [0, -1, -1, -1, 1, 1]

t_users = [[int(round(float(w), 0)) for w in row] for row in [line.strip().split("\t") for line in open(path+name, 'rb')]]
v_users = numpy.array(numpy.choose(t_users, choices))  #
v_books = v_users.T
del t_users

t0 = datetime.now()
ratings = []
for user in xrange(0, v_users.shape[0]):
    for book in xrange(0, v_users.shape[1]):
        if v_users[user, book] != choices[0]:
            ratings.append({"user": user, "book": book, "score": v_users[user, book]})
ratings = numpy.array(ratings)

clY = AdaptiveClustering(threshold=0.95)    # 81 clusters
clY.fit(v_books, debug=True)
clX = AdaptiveClustering(threshold=0.89)    # 4992 clusters
clX.fit(v_users, debug=True)

print "fitted both dimensions"

results = {"predicted": [], "correct": []}
# ten_fold = KFold(n=ratings.shape[0]-1, n_folds=10, shuffle=True)

# for train_indexes, test_indexes in ten_fold:
if True:
    clf = NearestCentroid(metric="cosine")
    art = ArtMAP(clf, choices)
    art.X_cluster = clX
    art.Y_cluster = clY
    art.fitted_X = True
    art.fitted_Y = True
    from sklearn.cross_validation import train_test_split
    train_indexes, test_indexes = train_test_split(ratings, train_size=0.90, test_size=0.10, random_state=0)
    X_train = []
    Y_train = []
    z_train = []
    X_test = []
    Y_test = []
    z_test = []
    print "spliting dataset"
    for score in train_indexes:  # ratings[train_indexes]:
        X_train.append(v_users[score['user']])
        Y_train.append(v_books[score['book']])
        z_train.append(score['score'])
    print "calling fit method"
    art.fit(X_train, Y_train, z_train, debug=True)
    del X_train, Y_train, z_train, train_indexes

    print "preparing to predict"
    for score in test_indexes:  # ratings[test_indexes]:
        X_test.append(v_users[score['user']])
        Y_test.append(v_books[score['book']])
        z_test.append(score['score'])

    results["predicted"] += art.predict(X_test, Y_test, debug=True)
    results["correct"] += z_test
    del X_test, Y_test, z_test, test_indexes

print "time taken", datetime.now() - t0
results['test_pr'] = numpy.choose([int(round(x, 0)) for x in results['predicted']], choices)
results['test_co'] = numpy.choose([int(x) for x in results['correct']], choices)

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
print "precision", precision_score(results['test_co'], results['test_pr'])
print "recall", recall_score(results['test_co'], results['test_pr'])
print "accuracy", accuracy_score(results['test_co'], results['test_pr'])
print "f-measure", f1_score(results['test_co'], results['test_pr'])

